#pragma once

#include "ssi_defines.h"
#include "ssi_includes.h"
#include "ssi_tnode.h"

#include <string>
#include <algorithm>
using std::string;
using std::reverse;

class SSI_SCRIPTDLL_API String2;

typedef SSI_SCRIPTDLL_API TNodeTree<String2> String2Tree;
typedef SSI_SCRIPTDLL_API TNode<String2> String2Node;

class SSI_SCRIPTDLL_API String2  
{
private:
  string str;
public:

	void CopyToBuffer(SSI_CHAR* In) const;
	SSI_INT64 ReverseFind(const SSI_CHAR* In, SSI_INT64 StartPos = -1, SSI_INT64 StopPos = -1);
	void Reverse();
	void SetWithinState(SSI_CHAR StartChar, SSI_CHAR EndChar);
	void SetAfterState(SSI_CHAR Char);
	void SetBeforeState(SSI_CHAR Char);
	SSI_INT64 FindOneOf(const String2& Str, SSI_INT64 Start = -1, SSI_INT64 Stop = -1) const;
	SSI_BOOL CheckChars(SSI_WORD wFlags) const;
	SSI_BOOL SetEndQuotes(SSI_BOOL bConvertExistingEnds = 0);
	SSI_CHAR chop(SSI_BOOL bFromStart = 0);
	SSI_BOOL CheckEndQuotes(SSI_BOOL bStrip = 0, SSI_BOOL bTrim = 0);
	SSI_INT64 SetAt(SSI_INT64 Pos, SSI_CHAR c);
	SSI_INT64 Format(const SSI_CHAR* fmt, ...);
	void SetQuoteState(SSI_BOOL bSet);
	SSI_CHAR GetAt(SSI_INT64 Pos) const;
	void Trim();
	void TrimRight();
	void TrimLeft();
	SSI_INT64 Parse(String2& Delimeters, String2Tree& Return, SSI_INT64 DelLen);
	SSI_INT64 Parse(String2& Delimeters, String2 &Return, String2* Tok = SSI_NULL, SSI_INT64 DelLen = -1);
	SSI_INT64 Parse(const char* Delimeters, String2 &Return, String2* Tok = SSI_NULL, SSI_INT64 DelLen = -1){String2 sTemp = Delimeters; return Parse(sTemp,Return,Tok,DelLen);};
	String2 Right(SSI_INT64 NumChars) const;
	String2 Left(SSI_INT64 NumChars) const;
	//String2 Left(SSI_INT64 NumChars);
  SSI_INT64 Find(const SSI_CHAR* In, SSI_INT64 StartPos = -1, SSI_INT64 StopPos = -1) const;
  SSI_INT64 Find(const String2 &In, SSI_INT64 StartPos = -1, SSI_INT64 StopPos = -1) const;
	String2 SubString(SSI_INT64 Start, SSI_INT64 Finish = -1) const;
	void Replace(const SSI_CHAR* Out, const SSI_CHAR* In);
	static void replace(string& s, const SSI_CHAR* Out, const SSI_CHAR* In);
	SSI_INT64 GetLength() const;
	SSI_BOOL operator ==(String2 &Other) const;
  SSI_BOOL operator ==(const SSI_CHAR* Other) const;
  String2& operator=(const String2& Other);
  String2& operator=(const SSI_CHAR* Other);
  String2 operator+(const String2& s2);
  String2 operator+(SSI_CHAR* s2);
	bool operator<(const String2& Other) const;
	bool operator<(const SSI_CHAR* Other) const;
//	SSI_CHAR& operator [](SSI_INT64 i);
	operator CSSI_CHAR*() const {return str.c_str();};
  const SSI_CHAR* Str() const;
	static SSI_INT64 GetSize(const SSI_CHAR* InStr);
	
  String2();
  String2(const SSI_CHAR* InitVal); 
  String2(SSI_CHAR InitChar);
  String2(const String2& Other);
	virtual ~String2();
protected:
private:
	static SSI_INT64 loc_copy(const SSI_CHAR* src, SSI_CHAR* dest);
	SSI_CHAR* Null();
  //SSI_BYTE CHECK_QUOTE_STATE;
  SSI_CHAR CHECK_WITHIN_SSI_CHAR_START;
  SSI_CHAR CHECK_WITHIN_SSI_CHAR_END;
  SSI_CHAR CHECK_BEFORE_SSI_CHAR;
  SSI_CHAR CHECK_AFTER_SSI_CHAR;
public:
	SSI_BOOL IsNumber(void);
	bool IsWhiteSpace(void);
	SSI_BOOL GetQuoteState(void) const;
};




